# import jusmargui
from PySide2.QtWidgets import (
    QApplication,
    QWidget,
    QTableWidgetItem,
    QTableWidget,
    QHeaderView,
    QAbstractItemView,
    QVBoxLayout,
    QTabWidget,
    QGroupBox,
    QLabel,
    QLineEdit,
    QHBoxLayout,
    QGridLayout,
    QComboBox,
    QPushButton,
    QListWidget,
    QDialog,
    QButtonGroup,
    QRadioButton,
    QCheckBox,
    QListWidgetItem,
    QMessageBox,
    QGraphicsColorizeEffect,
    QFileDialog,
    QSizePolicy,
)
from PySide2.QtCore import Qt, Signal
from PySide2.QtGui import QPixmap, QDoubleValidator, QIntValidator, QMouseEvent, QIcon
import sys
import csv
import os
import json
import subprocess
import copy
from datetime import datetime
from functools import partial
from gui.controls import envs
from .. import config as Config
from ..utils import Utils
from .. import message_box as MBox
from ..dlg_model_params import DlgModeResetCls
from ..params_table import ParamsTable, OnlyOneRowTable
from ..util.parameter_mapping_beam_and_mass_point import (
    keyMap,
    titleMap
)

# from ..lazy_table import LazyTable
import math
from ..custom_widget import (
    SelectBox,
    RadioBtnGroup,
    MultRadioBtnGroup,
    LineEditFloat,
    LineEditInt,
)
from ..beam_and_mass_point.add_tank import DlgAddTank
from ..util.utils_empty import filter_empty_data


def find_max_fourth_value(two_d_array, position):
    if not two_d_array:  # 如果数组为空，则返回None
        return None
    max_value = -math.inf  # 初始化最大值为负无穷大
    for sub_array in two_d_array:
        if len(sub_array) >= position + 1:  # 检查子数组长度是否至少为4
            fourth_value = sub_array[position]  # 提取第4位的值
            if fourth_value is None or fourth_value == "":  # 检查值是否为None
                continue
            if fourth_value > max_value:  # 比较并更新最大值
                max_value = fourth_value
    if max_value == -math.inf:
        return None
    return max_value  # 返回最大值


class CustomTabWidget(QTabWidget):
    add_tab_signal = Signal()

    def __init__(self, parent=None):
        super(CustomTabWidget, self).__init__(parent)
        self.initUI()

    def initUI(self):
        # 设置标签位置
        self.setTabPosition(QTabWidget.North)

        # 创建右侧按钮
        addBtn = QPushButton()
        self.set_button_image(addBtn, "icons/plugins/qmodeling/add.png")
        addBtn.clicked.connect(self.add_tab_signal.emit)
        # lab.setFixedSize(30, 20)

        # 将按钮添加到标签栏
        self.tabBar().setLayoutDirection(Qt.LeftToRight)

        self.setCornerWidget(addBtn, Qt.TopRightCorner)

    def get_all_tab_titles(self):
        """获取 QTabWidget 中所有标签页的标题"""
        titles = []
        for index in range(self.count()):
            titles.append(self.tabText(index))
        return titles

    def set_button_image(self, button, image_path):
        """设置按钮的图片，并保持等比宽高，同时设置边距"""
        pixmap = QPixmap(image_path)
        if pixmap.isNull():
            print("Error: Unable to load image.")
            return

        # 等比缩放图片到指定大小（15x15像素）
        scaled_pixmap = pixmap.scaled(
            15, 15, Qt.KeepAspectRatio, Qt.SmoothTransformation
        )

        # 将 QPixmap 转换为 QIcon
        icon = QIcon(scaled_pixmap)

        # 设置按钮图标和大小
        button.setIcon(icon)  # 使用 QIcon 设置图标
        button.setIconSize(scaled_pixmap.size())  # 设置图标大小
        button.setStyleSheet(
            """
                             QPushButton { 
                                margin-right:3px;
                                min-width: 25px !important; 
                                max-width: 25px !important; 
                                min-height: 15px !important; 
                                max-height: 15px !important;
                                border-bottom-left-radius: 0px;
                                border-bottom-right-radius: 0px; 
                             }"""
        )


# 新增行必须使用 addRow()
class BarTable(ParamsTable):
    pasteState = Signal(str)  # 粘贴开始和结束

    def __init__(self, rows=0, columns=2, isLibrary=False, parent=None):
        super(BarTable, self).__init__(rows, columns, isLibrary, parent)

    def paste_tb_text(self):
        self.incorrectFormatRowList = []
        try:
            self.pasteState.emit("start")
            text = QApplication.clipboard().text()
            pasteList = text.split("\n")
            # pasteList = [item for item in pasteList if item and item.strip()]
            # 复制后，尾部会有一个空字符串数组，需要去掉
            if len(pasteList) > 0:
                if pasteList[-1] == "":
                    pasteList.pop(-1)
            pasteList2D = []
            for row in pasteList:
                pasteList2D.append(row.split("\t"))
                # pasteList2D.append(re.split(r"[\t]", row))
            rows = len(pasteList)
            isMutli = self.isMutli(pasteList2D)
            indexes = self.selectedIndexes()
            if indexes:
                # 选中单元后粘贴
                for index in indexes:
                    index = index
                    break
                r, c = index.row(), index.column()  # 拿到选中的第一个单元格
                residueColumn = self.columnCount() - c
                if residueColumn < len(pasteList2D[0]):
                    isPaste = MBox.confirm(
                        f"粘贴数据包含{len(pasteList2D[0])}列，但表格仅剩{residueColumn}列，超出部分不会被粘贴。是否继续？",
                    )
                    if isPaste:
                        self.seletedToPaste(
                            isMutli, rows, r, c, pasteList2D, indexes, text
                        )
                else:
                    self.seletedToPaste(isMutli, rows, r, c, pasteList2D, indexes, text)
            else:
                # 直接粘贴
                sameIdeDict = {}
                # # 判断数据是否有id
                # hasId = True
                # if Utils.toInt(pasteList2D[0][0]) == "":
                #     # 没有id
                #     hasId = False
                if self.uniqueFlagColumn != -1:
                    # if not hasId:
                    #     pasteList2D = [[""] + sublist for sublist in pasteList2D]
                    copyData = pasteList2D.copy()
                    tableDict = self.getTableDict()
                    for addIndex in range(len(copyData) - 1, -1, -1):  # 倒序遍历
                        csvRow = copyData[addIndex]

                        if (
                            csvRow[self.uniqueFlagColumn] is not None
                            and str(csvRow[self.uniqueFlagColumn]) in tableDict
                        ):
                            sameIdeDict[tableDict[str(csvRow[1])]["row"]] = csvRow
                            # self.updateRowData(
                            #     tableDict[str(csvRow[self.uniqueFlagColumn])]["row"],
                            #     csvRow,
                            # )
                            del pasteList2D[addIndex]
                    self.addMulitRows(
                        pasteList2D, isAddIncrementing=True, isPastOrImport=True
                    )
                    if len(sameIdeDict) > 0:
                        isIdSame = MBox.confirm(
                            text=f"目标包含{str(len(sameIdeDict))}个相同id的数据!",
                            title="替换或跳过",
                            sureText="替换",
                            cancelText="跳过",
                        )
                        if isIdSame:
                            for row, value in sameIdeDict.items():
                                self.updateRowData(row, value, True)
                else:
                    self.addMulitRows(pasteList2D, isPastOrImport=True)
            self.sortTableByID()
            if len(self.incorrectFormatRowList) > 0:
                MBox.warning(
                    text=f"数据格式不正确!",
                )
                self.incorrectFormatRowList = []
            self.pasteState.emit("end")
        except Exception as e:
            print(e)
            self.pasteState.emit("end")
            return


# 创建一个自定义的 QListWidget 类
class CustomListWidget(QListWidget):
    double_click_signal = Signal(int, object)

    def __init__(self):
        super().__init__()

    def mouseDoubleClickEvent(self, event: QMouseEvent):
        # 捕获双击事件
        super().mouseDoubleClickEvent(event)  # 调用父类的 mouseDoubleClickEvent 方法
        current_row = self.currentRow()  # 获取当前选中的行号
        selected_item = self.item(current_row)  # 获取当前选中的项目
        if selected_item:
            self.double_click_signal.emit(current_row, selected_item)


class CGridLayout(QGridLayout):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAlignment(Qt.AlignTop)


class DlgBeamAndMassPoint(DlgModeResetCls):
    beamAndMassPoint_save_signal = Signal(object)
    materialLibraryLocking_update_signal = Signal(object)

    def __init__(self, parent=None, params={}):
        super().__init__(parent)
        title = f"梁与质量点-{params.get('title')or''}"
        self.setWindowTitle(title)
        self.resize(800, 900)

        self.isLoaded = False
        self.isImportOrPaste = False
        self.nodeNothingnes = False  # 节点不存在
        self.lastMaterial = []
        self.tabWidgetList = []


        layout = QVBoxLayout()

        self.materialFile = Config.cachePath + "materialLibrary.json"
        self.materialData = Utils.read_json(self.materialFile)
        self.options = []
        if self.materialData:
            for key, _ in self.materialData.items():
                self.options.append({"title": key, "value": key})

        # 节点
        gridGroupBox = QGroupBox("节点")
        gridLayout = QVBoxLayout()
        gridGroupBox.setLayout(gridLayout)
        self.gridTable = ParamsTable(rows=0, columns=7)
        self.gridTable.verticalHeader().setVisible(True)
        self.gridTable.setHorizontalHeaderLabels(
            [
                "节点号",
                "x坐标",
                "y坐标",
                "z坐标",
                "质量",
                "半径",
                "位置说明",
            ]
        )
        self.gridTable.rowSetInt([0])
        self.gridTable.rowSetFloat([1, 2, 3, 4, 5])
        self.gridTable.setAddIncrementing(True)
        self.gridTable.uniqueFlagColumn = 0
        gridLayout.addWidget(self.gridTable)

        gridBtnLayout = QHBoxLayout()
        addMainBtn = QPushButton("新增")
        importMainBtn = QPushButton("导入csv")
        clearMainBtn = QPushButton("清空")

        gridBtnLayout.setAlignment(Qt.AlignCenter)
        gridBtnLayout.addWidget(addMainBtn)
        gridBtnLayout.addWidget(importMainBtn)
        gridBtnLayout.addWidget(clearMainBtn)
        gridLayout.addLayout(gridBtnLayout)

        addMainBtn.clicked.connect(partial(self.on_addBtn_clicked, self.gridTable))
        importMainBtn.clicked.connect(
            partial(self.on_importBtn_clicked, self.gridTable, "gridTable")
        )
        clearMainBtn.clicked.connect(partial(self.on_clearBtn_clicked, self.gridTable))
        layout.addWidget(gridGroupBox)

        # 单元
        barGroupBox = QGroupBox("单元")
        barLayout = QVBoxLayout()
        barGroupBox.setLayout(barLayout)

        self.barTable = BarTable(rows=0, columns=7)
        self.barTable.verticalHeader().setVisible(True)
        self.barTable.setHorizontalHeaderLabels(
            [
                "单元号",
                "节点1",
                "节点2",
                "单元外半径",
                "等效厚度",
                "蒙皮厚度",
                "材料",
            ]
        )

        self.barTable.rowSetInt([0, 1, 2])
        self.barTable.rowSetFloat([3, 4, 5])
        self.barTable.rowSetSelect([6], options={"6": self.options})
        self.barTable.itemChanged.connect(self.conduitHeadChange)
        self.barTable.setAddIncrementing(True)
        self.barTable.pasteState.connect(self.pasteState)
        # self.barTable.noEditHint = "该数据已入库，不可修改单元号！"
        self.barTable.uniqueFlagColumn = 0
        barLayout.addWidget(self.barTable)

        barBtnLayout = QHBoxLayout()
        addBarBtn = QPushButton("新增")
        importBarBtn = QPushButton("导入csv")
        clearBarBtn = QPushButton("清空")

        barBtnLayout.setAlignment(Qt.AlignCenter)
        barBtnLayout.addWidget(addBarBtn)

        barBtnLayout.addWidget(importBarBtn)
        barBtnLayout.addWidget(clearBarBtn)
        barLayout.addLayout(barBtnLayout)
        layout.addWidget(barGroupBox)

        addBarBtn.clicked.connect(partial(self.on_addBtn_clicked, self.barTable))
        importBarBtn.clicked.connect(
            partial(self.on_importBtn_clicked, self.barTable, "barTable")
        )
        clearBarBtn.clicked.connect(partial(self.on_clearBtn_clicked, self.barTable))

        self.tabs = CustomTabWidget()
        self.tabs.tabBarDoubleClicked.connect(self.on_tab_double_clicked)
        self.tabs.add_tab_signal.connect(self.addTab)
        self.gridPage = QWidget()
        self.rodPage = QWidget()

        # 设置选项卡可关闭
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.on_tab_close_requested)

        layout.addWidget(self.tabs)

        cancelBtn = QPushButton("取消")
        okBtn = QPushButton("确定")
        btnLayout2 = QHBoxLayout()
        btnLayout2.setAlignment(Qt.AlignCenter)
        btnLayout2.addWidget(okBtn)
        btnLayout2.addWidget(cancelBtn)
        okBtn.clicked.connect(self.on_okBtn_clicked)
        cancelBtn.clicked.connect(self.close)
        layout.addLayout(btnLayout2)
        self.setLayout(layout)

        self.on_tab_count_changed()

        self.cacheFile = Config.cachePath + "beamAndMassPoint21.json"
        Utils.write_json(self.cacheFile, params)
        
        data = {}
        if Config.isLocation:
            self.cacheFile = Config.cachePath + "beamAndMassPoint.json"
            data = Utils.read_json(self.cacheFile)
        else:
            data = params.get("data") or {}
            
        tanks = data.get("tank") or {}
        for i, (key, value) in enumerate(tanks.items()):
            name = key
            site_point = value.get("site_point") or []
            self.createTank(name, i, site_point)
        self.tabs.setCurrentIndex(0)
        self.updateUI(data)
        Utils.handleTableNoEdit(data=data.get("grid") or [], table=self.gridTable)
        Utils.handleTableNoEdit(data=data.get("bar") or [], table=self.barTable)
        if Config.useLibraryLocking:
            self.lastMaterials = Utils.getTableLibrarysName(
                data=data.get("grid"), column=8
            )

    def on_tab_count_changed(self):
        if self.tabs.count() == 0:
            self.tabs.setStyleSheet(
                """
                            QTabWidget::pane:top {
                            top: 20px;
                             }"""
            )
        else:
            self.tabs.setStyleSheet(
                """
                            QTabWidget::pane:top {
                            top: 0px;
                             }"""
            )

    def addTab(self):
        grid = self.gridTable.getTableData()
        names = self.tabs.get_all_tab_titles()
        dlgAddTank = DlgAddTank.show(parent=self, params={"grid": grid, "names": names})
        dlgAddTank.ok_signal.connect(self.on_update_tank)

    def on_update_tank(self, type, index, data):
        name = data.get("name")
        site_point = data.get("site_point")
        if type == "add":
            index = self.tabs.count()
            self.createTank(name, index, site_point)
        else:
            self.tabs.setTabText(index, name)
            tab = self.tabs.widget(index)
            if tab:
                tab.setProperty("site_point", site_point)
            else:
                print("贮箱位置不对应！")

    def on_tab_double_clicked(self, index):
        grid = self.gridTable.getTableData()
        names = [self.tabs.tabText(i) for i in range(self.tabs.count()) if i != index]
        name = self.tabs.tabText(index)
        site_point = self.tabs.widget(index).property("site_point")
        item_data =  {"site_point": site_point, "name": name}
        
        dlgAddConnection = DlgAddTank.show(
            parent=self,
            params={
                "grid": grid,
                "index": index,
                "names": names,
                "data": item_data,
                "type": "edit",
            },
        )
        dlgAddConnection.ok_signal.connect(self.on_update_tank)

    def on_tab_close_requested(self, index):
        isDel = MBox.confirm("是否确认删除该连接?")
        if isDel:
            self.tabs.removeTab(index)
            self.tabWidgetList.pop(index)
            self.on_tab_count_changed()

    def createTank(self, name, index, site_point):
        self.tabWidgetList.append({})
        widgetDict = self.tabWidgetList[-1]

        layout = QHBoxLayout()
        pageWidget = QWidget()
        pageWidget.setLayout(layout)
        pageWidget.setProperty("site_point", site_point)
        self.tabs.addTab(pageWidget, name)

        panelLayout = QVBoxLayout()
        layout.addLayout(panelLayout)
        topGroupBox = QGroupBox("上底")
        panelLayout.addWidget(topGroupBox)
        topLayout = QVBoxLayout()
        topGroupBox.setLayout(topLayout)
        topSelectLayout = QHBoxLayout()
        widgetDict["top_dir"] = SelectBox(
            options=[{"title": "凹", "value": "凹"}, {"title": "凸", "value": "凸"}],
            flag="top",
            key="top_dir",
            onChanged=lambda *args, **kwargs: self.concaveConvexChanged(
                self, *args, **kwargs
            ),
        )
        widgetDict["top_typ"] = SelectBox(
            options=[
                {"title": "椭球", "value": "椭球"},
                {"title": "三心球", "value": "三心球"},
                {"title": "半椭球", "value": "半椭球"},
                {"title": "椭球内嵌", "value": "椭球内嵌"},
            ],
            flag="top",
            key="top_typ",
            onChanged=lambda *args, **kwargs: self.ballChanged(self, *args, **kwargs),
        )
        topSelectLayout.addWidget(widgetDict["top_dir"])
        topSelectLayout.addWidget(widgetDict["top_typ"])
        topSelectLayout.addStretch(1)

        topPanelLayout = QHBoxLayout()
        topPanelTable = OnlyOneRowTable(rows=1, columns=1, isNoAddAndDel=True)
        topPanelTable.verticalHeader().setVisible(True)
        topPanelTable.setFixedHeight(130)
        topPanelTable.setHorizontalHeaderLabels(
            [
                "尺寸",
            ]
        )
        topPanelTable.rowSetFloat([0])
        widgetDict["topTable"] = topPanelTable

        self.topImage = QLabel()
        self.topImage.setAlignment(Qt.AlignCenter)
        self.topImage.setFixedWidth(150)
        pixmap = QPixmap("")
        scaled_pixmap = pixmap.scaledToWidth(150, Qt.SmoothTransformation)
        self.topImage.setPixmap(scaled_pixmap)

        topPanelLayout.addWidget(topPanelTable)
        topPanelLayout.addStretch(1)
        topPanelLayout.addWidget(self.topImage)

        topLayout.addLayout(topSelectLayout)
        topLayout.addLayout(topPanelLayout)

        bottomGroupBox = QGroupBox("下底")
        panelLayout.addWidget(bottomGroupBox)
        bottomLayout = QVBoxLayout()
        bottomGroupBox.setLayout(bottomLayout)
        bottomSelectLayout = QHBoxLayout()
        bottomLayout.addLayout(bottomSelectLayout)
        widgetDict["bot_dir"] = SelectBox(
            options=[{"title": "凹", "value": "凹"}, {"title": "凸", "value": "凸"}],
            flag="bot",
            key="bot_dir",
            onChanged=lambda *args, **kwargs: self.concaveConvexChanged(
                self, *args, **kwargs
            ),
        )
        widgetDict["bot_typ"] = SelectBox(
            options=[
                {"title": "椭球", "value": "椭球"},
                {"title": "三心球", "value": "三心球"},
                {"title": "半椭球", "value": "半椭球"},
                {"title": "椭球内嵌", "value": "椭球内嵌"},
            ],
            flag="bot",
            key="bot_typ",
            onChanged=lambda *args, **kwargs: self.ballChanged(self, *args, **kwargs),
        )
        widgetDict["bot_quad"] = MultRadioBtnGroup(
            options=[{"title": "三维建模", "value": "三维建模"}],
            onChanged=lambda *args, **kwargs: self.tdChanged(*args, **kwargs),
        )
        bottomSelectLayout.addWidget(widgetDict["bot_dir"])
        bottomSelectLayout.addWidget(widgetDict["bot_typ"])
        bottomSelectLayout.addWidget(widgetDict["bot_quad"])

        tdWidget = QWidget()
        bottomLayout.addWidget(tdWidget)
        tdWidget.setVisible(False)
        tdLayout = QHBoxLayout()
        tdWidget.setLayout(tdLayout)
        widgetDict["tdWidget"] = tdWidget

        eleNoBox = QGroupBox("固定长度")
        tdLayout.addWidget(eleNoBox)
        eleNoGridLayout = QGridLayout()
        eleNoBox.setLayout(eleNoGridLayout)
        ringNumLab = QLabel("环向个数")
        eleNoGridLayout.addWidget(ringNumLab, 0, 0)
        widgetDict["ringNum"] = LineEditFloat()
        eleNoGridLayout.addWidget(widgetDict["ringNum"], 0, 1)
        heightNumLab = QLabel("高度个数")
        eleNoGridLayout.addWidget(heightNumLab, 1, 0)
        widgetDict["heightNum"] = LineEditFloat()
        eleNoGridLayout.addWidget(widgetDict["heightNum"], 1, 1)

        tdGridlayout = QGridLayout()
        tdLayout.addLayout(tdGridlayout)
        tdIdLab = QLabel("初始编号")
        tdGridlayout.addWidget(tdIdLab, 0, 0)
        widgetDict["tdId"] = LineEditInt()
        tdGridlayout.addWidget(widgetDict["tdId"], 0, 1)
        matLab = QLabel("材料")
        tdGridlayout.addWidget(matLab, 1, 0)
        widgetDict["Mat"] = SelectBox(
            options=self.options
        )
        tdGridlayout.addWidget(widgetDict["Mat"], 1, 1)
        thickLab = QLabel("厚度")
        tdGridlayout.addWidget(thickLab, 2, 0)
        widgetDict["Thick"] = LineEditFloat()
        tdGridlayout.addWidget(widgetDict["Thick"], 2, 1)

        bottomSelectLayout.addStretch(1)
        bottomPanelLayout = QHBoxLayout()
        bottomPanelTable = OnlyOneRowTable(rows=1, columns=1, isNoAddAndDel=True)
        bottomPanelTable.setHorizontalHeaderLabels(["尺寸"])
        bottomPanelTable.verticalHeader().setVisible(True)
        bottomPanelTable.setFixedHeight(130)
        bottomPanelTable.rowSetFloat([0])
        widgetDict["botTable"] = bottomPanelTable

        self.bottomImage = QLabel()
        self.bottomImage.setAlignment(Qt.AlignCenter)
        self.bottomImage.setFixedWidth(150)
        pixmap = QPixmap("")
        scaled_pixmap = pixmap.scaledToWidth(150, Qt.SmoothTransformation)
        self.bottomImage.setPixmap(scaled_pixmap)

        bottomPanelLayout.addWidget(bottomPanelTable)
        bottomPanelLayout.addStretch(1)
        bottomPanelLayout.addWidget(self.bottomImage)
        bottomLayout.addLayout(bottomPanelLayout)

        gridLayout1 = QGridLayout()
        layout.addLayout(gridLayout1)
        layout.setStretchFactor(panelLayout, 3)
        layout.setStretchFactor(gridLayout1, 2)

        baffleLayout = QGridLayout()
        baffleBox = QGroupBox("防晃板")
        baffleBox.setLayout(baffleLayout)
        gridLayout1.addWidget(baffleBox, 0, 0, 1, 2)
        self.baffleTable = ParamsTable(rows=0, columns=3)
        self.baffleTable.verticalHeader().setVisible(True)
        self.baffleTable.setHorizontalHeaderLabels(
            [
                "位置",
                "形式",
                "尺寸",
            ]
        )
        self.baffleTable.rowSetFloat([0, 2])
        self.baffleTable.rowSetSelect(
            [1],
            options={
                "1": [
                    {"title": "ring", "value": "ring"},
                ]
            },
        )
        baffleLayout.addWidget(self.baffleTable)
        widgetDict["baffleTable"] = self.baffleTable

        crossBox = QGroupBox("十字隔板的位置")
        gridLayout1.addWidget(crossBox, 1, 0, 1, 2)
        crossGridLayout = QGridLayout()
        crossBox.setLayout(crossGridLayout)
        topEndLab = QLabel("上端")
        crossGridLayout.addWidget(topEndLab, 0, 0)
        widgetDict["topEnd"] = LineEditFloat()
        crossGridLayout.addWidget(widgetDict["topEnd"], 0, 1)
        botEndLab = QLabel("下端")
        crossGridLayout.addWidget(botEndLab, 1, 0)
        widgetDict["botEnd"] = LineEditFloat()
        crossGridLayout.addWidget(widgetDict["botEnd"], 1, 1)

        densLab = QLabel("液体密度")
        gridLayout1.addWidget(densLab, 2, 0)
        widgetDict["dens"] = LineEditFloat()
        gridLayout1.addWidget(widgetDict["dens"], 2, 1)
        radiusLab = QLabel("贮箱外半径")
        gridLayout1.addWidget(radiusLab, 3, 0)
        widgetDict["radius"] = LineEditFloat()
        gridLayout1.addWidget(widgetDict["radius"], 3, 1)
        radiusInLab = QLabel("隧道管半径")
        gridLayout1.addWidget(radiusInLab, 4, 0)
        widgetDict["radius_in"] = LineEditFloat()
        gridLayout1.addWidget(widgetDict["radius_in"], 4, 1)
        tankTrjMassLab = QLabel("弹道贮箱非质量")
        gridLayout1.addWidget(tankTrjMassLab, 5, 0)
        widgetDict["tank_trj_mass"] = LineEditFloat()
        gridLayout1.addWidget(widgetDict["tank_trj_mass"], 5, 1)

        self.tabs.setCurrentIndex(index)

        self.on_tab_count_changed()

    def pasteState(self, state):
        if state == "start":
            self.nodeNothingnes = False
            self.isImportOrPaste = True
        else:
            self.isImportOrPaste = False
            if self.nodeNothingnes == True:
                self.nodeNothingnes = False
                MBox.warning(f"节点不存在！")

    def on_addBtn_clicked(self, table):
        table.add()

    def on_importBtn_clicked(self, table, flag):
        filePath = Utils.ImportFile()
        if filePath:
            _, fileExtension = os.path.splitext(filePath)
            fileExtension = fileExtension.lower()
            if fileExtension == ".json":
                self.loadTableList(filePath, table, flag)
            elif fileExtension == ".csv":
                self.load_csv(filePath, table, flag)

    def updateUI(self, data):
        self.isLoaded = False
        if data:
            try:
                grid = data.get("grid") or []
                bar = data.get("bar") or []
                for rowData in grid:
                    self.gridTable.addRow(rowData=rowData)
                for rowData in bar:
                    self.barTable.addRow(rowData=rowData)
                tanks = data.get("tank") or {}
                if tanks:
                    for i, (key, value) in enumerate(tanks.items()):
                        widgetDict = self.tabWidgetList[i]
                        for itemKey, itemValue in value.items():
                            widgetKey = titleMap.get(itemKey) or itemKey
                            if widgetKey == "site_point" and widgetKey == "tdWidget":
                                continue 
                            if widgetKey == "topTable" or widgetKey == "botTable" and isinstance(itemValue, list):
                                tabList = [[item] for item in itemValue]
                                for row, rowData in enumerate(tabList):
                                    widgetDict[widgetKey].fillRowData(row=row, rowData=rowData)
                            elif widgetKey == "baffleTable" and isinstance(itemValue, list):
                                widgetDict[widgetKey].setRowCount(0)
                                for baf in itemValue:
                                    widgetDict[widgetKey].addRow(rowData=baf)
                            elif widgetKey == "bot_quad" and isinstance(itemValue, dict):
                                if  itemValue:
                                    # 有三维建模
                                    widgetDict[widgetKey].setValue(["三维建模"])
                                    widgetDict["tdWidget"].setVisible(True)
                                    for quadKey, quadValue in itemValue.items():
                                        qusdWidgetKey = titleMap.get(quadKey) or quadKey 
                                        if qusdWidgetKey == "ele_no" and isinstance(quadValue, list):
                                            # 固定长度
                                            values = ["ringNum", "heightNum"]
                                            for i, v in enumerate(quadValue):
                                                if i < len(values):
                                                    widgetDict[values[i]].setValue(v)
                                        else:
                                            if qusdWidgetKey in widgetDict:
                                                widgetDict[qusdWidgetKey].setValue(quadValue)
                                continue
                            elif widgetKey == "cross" and isinstance(itemValue, list):
                                # 十字隔板
                                values = ["topEnd", "botEnd"]
                                for i, v in enumerate(itemValue):
                                    if i < len(values):
                                        widgetDict[values[i]].setValue(v)
                            else:
                                if widgetKey in widgetDict:
                                    widgetDict[widgetKey].setValue(itemValue)
                
                self.isLoaded = True
            except Exception as e:  # 捕获其他所有异常
                self.isLoaded = True

    def on_okBtn_clicked(self):
        grid = self.gridTable.getTableDatatFirstNoNull()
        if isinstance(grid, int):
            MBox.warning(f"节点 第{grid}行节点号不可为空!")
            return
        if isinstance(grid, str):
            MBox.warning(f"节点 第{grid}行节点号已存在!")
            return
        bar = self.barTable.getTableDatatFirstNoNull()
        if isinstance(bar, int):
            MBox.warning(f"单元 第{bar}行单元号不可为空!")
            return
        if isinstance(bar, str):
            MBox.warning(f"单元 第{bar}行单元号已存在!")
            return
        # grid = Utils.filter_dict_list(grid)
        bar = Utils.filter_dict_list(bar)

        data = {"grid": grid, "bar": bar, "type": "bar_conm", "tank": {}} 
        bot_quad = ["ringNum","heightNum","tdId","Mat","Thick"]  # 三维建模
        tankDict = {}
        data["tank"] = tankDict
        
        
        for i, widgetDict in enumerate(self.tabWidgetList):
            name = self.tabs.tabText(i)
            tankDict[name] = {}
            # site_point
            tankDict[name]["site_point"] = self.tabs.widget(i).property("site_point")
            # 三维建模
            bot_quadData = {}
            bot_quadData["ele_no"] = [None, None]
            
            # 十字隔板
            tankDict[name]["cross"] = [None, None]
            
            for key, widget in widgetDict.items():
                if key == "tdWidget":
                    continue

                if isinstance(widget, QTableWidget):
                    if key == "topTable" or key == "botTable":
                        tankDict[name][keyMap[key]] = [row[0] for row in widgetDict[key].getTableData()]
                    elif key == "baffleTable":
                        tankDict[name][keyMap[key]] = widgetDict[key].getTableData()
                else:
                    if key == "bot_quad":
                        # 三维建模
                        value = widgetDict["bot_quad"].getValue()
                        if value:
                            tankDict[name]["bot_quad"] = bot_quadData
                    elif key in bot_quad:
                        # 三维建模 内容
                        if key == "ringNum":    
                            bot_quadData["ele_no"][0] = widgetDict[key].getValue()
                        elif key == "heightNum":
                            bot_quadData["ele_no"][1] = widgetDict[key].getValue()
                        else:
                            bot_quadData[keyMap[key]] = widgetDict[key].getValue()
                    else:
                        # 其他
                        if key == "topEnd":
                            tankDict[name]["cross"][0] = widgetDict[key].getValue()
                        elif key == "botEnd":
                            tankDict[name]["cross"][1] = widgetDict[key].getValue()
                        else:
                            tankDict[name][keyMap[key]] = widget.getValue()
            
        filterDict = filter_empty_data(data)
        filterDict["grid"] = grid
        self.cacheFile = Config.cachePath + "beamAndMassPoint.json"
        Utils.write_json(self.cacheFile, filterDict)
        if Config.isLocation:
            Utils.write_json(self.cacheFile, data)
        self.close()
        # if Config.useLibraryLocking:
        #     unique_library = Utils.updateLockingLibrary(
        #         dataList=[[grid, 8]],
        #         lastSelects=self.lastMaterials,
        #         library=self.materialData,
        #         file=Config.materialTable,
        #     )
        #     if unique_library:
        #         if hasattr(envs, "ipimas_changeLockMaterial"):
        #             envs.ipimas_changeLockMaterial()
        #         self.materialLibraryLocking_update_signal.emit(unique_library)
        self.beamAndMassPoint_save_signal.emit(filterDict)

    def on_clearBtn_clicked(self, table):
        table.clearRow()

    def on_delTankBarBtn_clicked(self):
        current_row = self.tankListWidget.currentRow()  # 获取当前选中的行号
        if current_row != -1:  # 如果有选中的项目
            isDel = MBox.confirm(
                "是否确认删除当前选中的贮箱?",
            )
            if isDel:
                self.tankListWidget.takeItem(current_row)  # 删除当前选中的项目
        else:
            MBox.warning("请选择要删除的行")


    def load_csv(self, filename, table, flag):
        if flag == "barTable":
            data = Utils.loadCsv(
                filename,
                labList=[
                    "单元号",
                    "节点1",
                    "节点2",
                    "单元外半径",
                    "等效厚度",
                    "蒙皮厚度",
                    "材料",
                ],
            )
        else:
            data = Utils.loadCsv(
                filename,
                labList=[
                    "节点号",
                    "x坐标",
                    "y坐标",
                    "z坐标",
                    "质量",
                    "半径",
                    "蒙皮厚度",
                    "等效厚度",
                    "材料",
                    "位置说明",
                ],
            )
        if data:
            copyCsvData = data.copy()
            idDict = table.getTableDict()
            try:
                self.nodeNothingnes = False
                if flag == "barTable":
                    self.isImportOrPaste = True
                for addIndex in range(len(copyCsvData) - 1, -1, -1):  # 倒序遍历
                    csvRow = copyCsvData[addIndex]
                    # 更新同id
                    if (
                        csvRow[0] is not None
                        and csvRow[0] != ""
                        and str(csvRow[0]) in idDict
                    ):
                        table.updateRowData(idDict[str(csvRow[0])]["row"], csvRow)
                        del data[addIndex]
                table.addMulitRows(data)
                if flag == "barTable":
                    self.isImportOrPaste = False
                if self.nodeNothingnes == True:
                    self.nodeNothingnes = False
                    MBox.warning(f"节点不存在！")
            except Exception as e:
                if flag == "barTable":
                    self.isImportOrPaste = False
                    self.nodeNothingnes = False
                print(e)

    def loadTableList(self, file, table):
        data = Utils.read_json(file)
        for rowData in data:
            table.addRow(rowData=rowData)

    def setTableFixeHeight(self, table, patchHeight=0):
        total_height = table.rowHeight(0)
        horizontal_header_height = table.horizontalHeader().height()
        table.setFixedHeight(total_height + horizontal_header_height + patchHeight)

    def conduitHeadChange(self, item):
        if not self.isLoaded:
            return
        row = item.row()
        column = item.column()
        if column != 1 and column != 2:
            return
        text = self.barTable.item(row, column).text()
        value = Utils.toIntOrNone(text)
        nodeDict = self.gridTable.getColumnDict()
        if value is not None and value not in nodeDict:
            item.setText("")
            if not self.isImportOrPaste:
                MBox.warning(f"设置的节点号不存在！")
            else:
                self.nodeNothingnes = True


    def concaveConvexChanged(self, *args, **kwargs):
        type = args[3]
        value = args[1]
        if type == "bot":
            self.updateBotTyp(value)

    def updateBotTyp(self, value):
        widgetDict = self.getCurrentWidgetDict()
        if value == "凸":
            widgetDict["bot_typ"].updateItem(
                [
                    {"title": "椭球", "value": "椭球"},
                    {"title": "三心球", "value": "三心球"},
                    {"title": "椭球内嵌", "value": "椭球内嵌"},
                    {"title": "半椭球", "value": "半椭球"},
                    {"title": "球锥球", "value": "球锥球"},
                    {"title": "锥加凹球", "value": "锥加凹球"},
                ]
            )
        else:
            widgetDict["bot_typ"].updateItem(
                [
                    {"title": "椭球", "value": "椭球"},
                    {"title": "三心球", "value": "三心球"},
                    {"title": "椭球内嵌", "value": "椭球内嵌"},
                    {"title": "半椭球", "value": "半椭球"},
                ]
            )

    def ballChanged(self, *args, **kwargs):
        type = args[1]
        key = f"{args[3]}Table"
        self.updateBallTable(type, key)

    def updateBallTable(self, value, key):
        widgetDict = self.getCurrentWidgetDict()
        if value == "椭球":
            widgetDict[key].setCustomRowCount(1)
        elif value == "三心球":
            widgetDict[key].setCustomRowCount(5)
        elif value == "球锥球":
            widgetDict[key].setCustomRowCount(6)
        elif value == "锥加凹球":
            widgetDict[key].setCustomRowCount(4)
        elif value == "椭球内嵌":
            widgetDict[key].setCustomRowCount(2)
        elif value == "半椭球":
            widgetDict[key].setCustomRowCount(3)
        else:
            widgetDict[key].setCustomRowCount(1)

    def tdChanged(self, *args, **kwargs):
        widgetDict = self.getCurrentWidgetDict()
        tdValue = widgetDict["bot_quad"].getValue()
        if tdValue and len(tdValue) >= 1:
            widgetDict["tdWidget"].setVisible(True)
        else:
            widgetDict["tdWidget"].setVisible(False)



    def on_item_count_changed(self):
        if self.tankListWidget.count() > 0:
            self.tankContentWidget.setVisible(True)
        else:
            self.tankContentWidget.setVisible(False)

    def set_button_image(self, button, image_path):
        """设置按钮的图片，并保持等比宽高，同时设置边距"""
        pixmap = QPixmap(image_path)
        if pixmap.isNull():
            print("Error: Unable to load image.")
            return

        # 等比缩放图片到指定大小（15x15像素）
        scaled_pixmap = pixmap.scaled(
            15, 15, Qt.KeepAspectRatio, Qt.SmoothTransformation
        )

        # 将 QPixmap 转换为 QIcon
        icon = QIcon(scaled_pixmap)

        # 设置按钮图标和大小
        button.setIcon(icon)  # 使用 QIcon 设置图标
        button.setIconSize(scaled_pixmap.size())  # 设置图标大小
        # button.setFixedSize(20, 20)  # 强制设置按钮的宽高为25像素（15 + 2 * 5）
        button.setStyleSheet(
            "QPushButton { min-width: 20px !important; min-height: 20px !important; max-width: 20px !important; max-height: 20px !important; }"
        )
        
    def getCurrentWidgetDict(self):
        tabIndex = self.tabs.currentIndex()
        return self.tabWidgetList[tabIndex]


# if __name__ == "__main__":
#     app = QApplication(sys.argv)
#     window = BeamAndMassPointDialog()
#     window.show()
#     sys.exit(app.exec_())
